package com.lsb.controller;


import cn.hutool.http.HttpResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lsb.pojo.Submit;
import com.lsb.pojo.UserVerifyForRegister;
import com.lsb.response.Result;
import com.lsb.service.SubmitService;
import com.lsb.service.UserService;
import com.lsb.utils.MyJsonUtils;
import com.lsb.utils.TencentCaptchaUtils;
import com.lsb.vo.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author liusibo
 * @since 2021-06-09
 */
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {

    @Autowired
    UserService userService;

    @Autowired
    SubmitService submitService;

    @Autowired
    PasswordEncoder passwordEncoder;

    @PostMapping("/register")
    void register(@RequestBody UserVerifyForRegister userVerify, HttpServletResponse response)throws Exception{
        //后端校验所需的参数
        String RAND_STR = userVerify.getRandstr();
        String TICKET = userVerify.getTicket();
        Long APP_ID = 2068453879L;
        String APP_SECRET = "0QnjIV2lbyN6lSxkVL5O7Mw**";
        String SECRET_ID = "AKIDkHZbMr52iOoyrUqvjGWUBbldEYcQxEEx";
        String SECRET_KEY = "TfZDagV4NQCgusZz92ez4sPgfOq1u97p";
        Result result = TencentCaptchaUtils.authenticationCaptcha(SECRET_ID,SECRET_KEY,APP_ID,APP_SECRET,TICKET,RAND_STR);
        //如果校验失败,则告知前端,图形验证错误,不可进行登录
        if((int)result.getData().get("code")!=1){
            try {
                log.info("图形验证码后端校验失败!");
                MyJsonUtils.WriteJSON(response,Result.error().message("校验失败"));
                //直接返回null,不进行用户名和密码的校验了
                return ;
            } catch (ServletException e) {
                e.printStackTrace();
            }
        }
        //如果后端校验成功,操作数据库进行用户的注册
        com.lsb.pojo.User user = new com.lsb.pojo.User();
        String password = userVerify.getPassword();
        user.setPassword(passwordEncoder.encode(password));
        user.setUsername(userVerify.getUsername());
        user.setRealName(userVerify.getRealName());
        user.setTelephoneNumber(userVerify.getTelephoneNumber());
        user.setIdentityNumber(userVerify.getIdentityNumber());
        log.info("注册用户:"+user);
        LambdaQueryWrapper<com.lsb.pojo.User> wrapper = new LambdaQueryWrapper<>();
        //如果注册成功,查找该用户
        wrapper.eq(com.lsb.pojo.User::getUsername,userVerify.getUsername());
        boolean isSuccees = false;
        try {
            isSuccees = userService.save(user);
        } catch (Exception e) {
            result = Result.error().message("注册失败");
            MyJsonUtils.WriteJSON(response,result);
        }
        if(isSuccees){
            user = userService.getOne(wrapper);
            // 获取当前时间
            LocalDateTime nowTime = LocalDateTime.now();
            int hour = nowTime.getHour();
            log.info("注册时间:"+hour);
            if(hour==0 || hour==1 || hour==2){
                //插入该注册用户今天的打卡记录
                submitService.insertRegisterSubmit(user,1);
            }
            else if(hour>=3){
                //插入注册用户今天和明天的打卡记录
                submitService.insertRegisterSubmit(user,2);
            }
            result = Result.ok().message("注册成功");
            MyJsonUtils.WriteJSON(response,result);
        }
        else {
            result = Result.error().message("注册失败");
            MyJsonUtils.WriteJSON(response,result);
        }
    }

    @PostMapping("/modifyPersonalInformation")
    void modifyPersonalInformation(@RequestBody LinkedHashMap<String,String> map,HttpServletResponse response)throws Exception{
        System.out.println(map);
        userService.modifyPersonalInformation(map,response);
    }

    @GetMapping("/formData")
    @PreAuthorize("hasAnyRole('user','admin')")
    void formData(HttpServletResponse response, Authentication authentication)throws Exception{
        //根据sessionId从对应的安全上下文context中拿到用户认证信息authentication，再拿到UserDetails
        User userDetails = (User) authentication.getPrincipal();
        //拿到username
        String username = userDetails.getUsername();
        //根据username查找到该用户的submit集合
        LambdaQueryWrapper<Submit> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Submit::getUsername,username);
        List<Submit> submitList = submitService.list(wrapper);
        //由于定时任务的缘故，取最后一个元素和倒数第二个元素，分别比较一下数据库日期和当前日期是否在同一天，必定有一个是同一天
        Submit submit = submitList.get(submitList.size() - 1);
        SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd");
        boolean isSameDay = fmt.format(new Date()).equals(fmt.format(submit.getCreateTime()));
        if(isSameDay){
            Result result = Result.ok().message("表单自动填充用户基本信息").data("formData",submit);
            MyJsonUtils.WriteJSON(response,result);
            return;
        }
        //该用户的倒数第二条提交记录
        Submit submit2 = submitList.get(submitList.size() - 2);
        isSameDay = fmt.format(new Date()).equals(fmt.format(submit2.getCreateTime()));
        if(isSameDay){
            Result result = Result.ok().message("表单自动填充用户基本信息").data("formData",submit2);
            MyJsonUtils.WriteJSON(response,result);
            return;
        }
        //防止有什么意外，最后来一个json格式的错误回显
        Result result = Result.error();
        MyJsonUtils.WriteJSON(response,result);
    }

    @GetMapping("/testAdmin")
    @PreAuthorize("hasRole('admin')")
    void testAdmin(HttpServletResponse response)throws Exception{
        //返回json格式数据给前端
        Result result = Result.ok().message("是管理员用户");
        MyJsonUtils.WriteJSON(response,result);
    }

    @GetMapping("/allUsers")
    @PreAuthorize("hasRole('admin')")
    void allUsers(HttpServletResponse response)throws Exception{
        List<com.lsb.pojo.User> userList = userService.getAllUsersIgnoreLogicDelete();
        List<UserVO> userVOList = new ArrayList<>();
        userList.forEach(user -> {
            UserVO userVO = new UserVO(user.getId(),user.getUsername(),user.getRealName(),
                    user.getTelephoneNumber(),user.getIdentityNumber(),user.getRole(),user.getLogicDelete().toString());
            userVOList.add(userVO);
        });
        userVOList.forEach(userVO -> {
            if(userVO.getRole().equals("ROLE_user")){
                userVO.setRole("普通用户");
            }
            else if(userVO.getRole().equals("ROLE_admin")){
                userVO.setRole("管理员用户");
            }
            if(userVO.getIsForbidden().equals("0")){
                userVO.setIsForbidden("正常");
            }
            else if(userVO.getIsForbidden().equals("1")){
                userVO.setIsForbidden("被禁用");
            }
        });
        //返回json格式数据给前端
        Result result = Result.ok().message("用户列表").data("userList",userVOList);
        MyJsonUtils.WriteJSON(response,result);
    }

    @GetMapping("/forbidden/{id}")
    @PreAuthorize("hasRole('admin')")
    void forbiddenUser(HttpServletResponse response, @PathVariable("id") Integer id)throws Exception{
        com.lsb.pojo.User user = userService.getById(id);
        //用户账号被逻辑删除了,直接返回该账号已被禁用给前端
        if(user==null){
            Result result = Result.error().message("该账号已被禁用");
            MyJsonUtils.WriteJSON(response,result);
        }
        else if(user.getRole().equals("ROLE_admin")){
            //不可封禁管理员账号,返回json格式数据给前端
            Result result = Result.error().message("无法禁用管理员账号");
            MyJsonUtils.WriteJSON(response,result);
        }
        else {
            userService.removeById(id);
            //返回json格式数据给前端
            Result result = Result.ok().message("禁用成功");
            MyJsonUtils.WriteJSON(response,result);
        }
    }

    //解禁账号
    @GetMapping("/save/{id}")
    @PreAuthorize("hasRole('admin')")
    void saveUser(HttpServletResponse response, @PathVariable("id") Integer id)throws Exception{
        com.lsb.pojo.User user = userService.getUserByIdIgnoreLogicDelete(id);
        //先判断空,防止空指针NullPointerException
        if(user==null){
            Result result = Result.error().message("用户不存在");
            MyJsonUtils.WriteJSON(response,result);
        }
        else if(user.getLogicDelete()==0){
            Result result = Result.error().message("账号状态正常");
            MyJsonUtils.WriteJSON(response,result);
        }
        else if(user.getLogicDelete()==1){
            userService.updateUserByIdIgnoreLogicDelete(user.getId());
            Result result = Result.ok().message("账号解禁成功");
            MyJsonUtils.WriteJSON(response,result);
        }
    }

}

